package gameobjects;

import java.awt.Canvas;
import java.awt.Component;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import resources.Sprite;

/** */
public class Button extends MouseAdapter {
    /** */
    private Sprite sprite;
    /** */
    private int x;
    /** */
    private int y;
    /** */
    private State state;
    /** */
    private Rectangle bounds;
    /** */
    private boolean down;
    /** */
    private boolean in;
    /** */
    private Runnable action;

    /** */
    private static enum State {
        DEFAULT(0),
        HOVER(1),
        PRESSED(2);

        /** */
        private int index;

        /** */
        private State(int id) {
            index = id;
        }

        /** */
        public int getIndex() {
            return index;
        }
    }

    /**
     * @param newSprite - the sprite.
     * @param newX - centre x position.
     * @param newY - top y position.
     */
    public Button(final Sprite newSprite, final int newX, final int newY,
            Runnable newAction) {
        sprite = newSprite;
        x = newX - sprite.getImage().getWidth() / 6;
        y = newY;
        bounds = new Rectangle(x, y, sprite.getImage().getWidth() / 3, sprite
                .getImage().getHeight());
        state = State.DEFAULT;
        action = newAction;
    }

    /** @param g - the Graphics context to draw on. */
    public final void draw(final Graphics g) {
        sprite.draw(g, state.getIndex(), x, y);
    }

    @Override
    public final void mouseMoved(final MouseEvent e) {
        if (bounds.contains(e.getPoint())) {
            in = true;
        } else {
            in = false;
        }
        updateState();
    }

    @Override
    public final void mouseDragged(final MouseEvent e) {
        if (bounds.contains(e.getPoint())) {
            in = true;
        } else {
            in = false;
        }
        updateState();
    }

    @Override
    public final void mousePressed(final MouseEvent e) {
        if ((e.getModifiersEx() & MouseEvent.BUTTON1_DOWN_MASK) != 0) {
            down = true;
            updateState();
        }
    }

    @Override
    public final void mouseReleased(final MouseEvent e) {
        if ((e.getModifiersEx() & MouseEvent.BUTTON1_DOWN_MASK) == 0) {
            down = false;
            updateState();
            if (in) {
                action.run();
            }
        }
    }

    /** */
    private void updateState() {
        if (in) {
            if (down) {
                state = State.PRESSED;
            } else {
                state = State.HOVER;
            }
        } else {
            state = State.DEFAULT;
        }
    }
}
